#ifndef _NET_SERVER_H_
#define _NET_SERVER_H_

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>

#define NET_MAX_REQUEST 10

class NetServer{
    public:
        NetServer(){
            FD_ZERO(&readfd);
        }
        NetServer(int port, int max_request = NET_MAX_REQUEST){
            m_max_request = NET_MAX_REQUEST;
            FD_ZERO(&readfd);
            Listen(port);
        }
        ~NetServer(){
            if(sockfd>0){
                close(sockfd);
            }
        }

        bool Listen(int port){
            struct sockaddr_in server_sockaddr;

            if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
                return false;
            }

            server_sockaddr.sin_family=AF_INET;
            server_sockaddr.sin_port=htons(port);
            server_sockaddr.sin_addr.s_addr=INADDR_ANY;
            bzero(&(server_sockaddr.sin_zero),8);
            if(bind(sockfd, (struct sockaddr*)&server_sockaddr, sizeof(struct sockaddr)) == -1){
                return false;
            }
            printf("bind success!\n");
            if(listen(sockfd, m_max_request) == -1){
                return false;
            }
            fprintf(stdout, "listening port[%d]....\n", port);
            FD_SET(sockfd,&readfd);
            return true;
        }

        int Accept(){
            if(select(m_max_request, &readfd, NULL, NULL, (struct timeval *)0)>0){
                if(FD_ISSET(sockfd,&readfd)>0){
                    socklen_t sin_size = sizeof(struct sockaddr_in);
                    struct sockaddr_in client_sockaddr;
                    //return accept(sockfd, (struct sockaddr*)&client_sockaddr, &sin_size);
                    return accept(sockfd, (struct sockaddr*)NULL, NULL);
                }
            }
            return -1;
        }

        int Recv(int fd, void* buf, int size){
            /*
            fd_set fdset;
            FD_ZERO(&readfd);
            FD_SET(fd, &fdset);
            if(select(1, &fdset, NULL, NULL, (struct timeval *)0)>0){
                if(FD_ISSET(fd, &fdset)>0){
                    return recv(*client_fd, buf, size, 0);
                }
            }
            return -1;
            */
            return recv(fd, buf, size, 0);
        }
        int Send(int fd, void* buf, int size){
            return send(fd, buf, size, 0);
        }
        void Close(){close(sockfd);}

    private:
        fd_set readfd;
        int sockfd;

        int m_max_request;
};

#endif
